package ro.cityprojects.adminloc.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import ro.cityprojects.adminloc.dao.BasicRepository;
import ro.cityprojects.adminloc.entities.Person;
import ro.cityprojects.adminloc.exceptions.EntityNotFoundException;
import ro.cityprojects.adminloc.exceptions.ValidationException;
import ro.cityprojects.adminloc.metadata.EntityMetadata;

import java.math.BigDecimal;
import java.util.Random;
import java.util.Set;

/**
 * PersonServiceImpl class
 *
 * @author bogdan.solga
 *
 * Date: 05.06.2013, time: 09:44
 */
@Service
public class PersonServiceImpl extends BaseService implements PersonService {

    private static final Logger log = LoggerFactory.getLogger(PersonServiceImpl.class);

    @Autowired
    private BasicRepository<Integer, Person> repository;

    @Override
    public String[] getDefaultFields() {
        return new String[]{"id", "firstName", "lastName", "userName", "personalIdentifier", "age", "email", "mobilePhoneNumber", "homePhoneNumber"};
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public void save(Person person) throws ValidationException {
        //TODO: add a field in the UI for the personal identifier
        person.setPersonalIdentifier(new BigDecimal(new Random().nextInt()));

        repository.save(person);
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public String get(Integer primaryKey, String includedFields) throws EntityNotFoundException {
        Person person = repository.get(Person.class, primaryKey);

        String[] outputFields = getOutputFields(includedFields, getDefaultFields());

        return serialize(person, outputFields);
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public String getAll(String filterName, String filterValue, String includedFields) {
        Set<Person> persons = repository.getAll(Person.class, filterName, filterValue);

        String[] outputFields = getOutputFields(includedFields, getDefaultFields());

        return serialize(persons, outputFields);
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public void update(Person person, Integer primaryKey) throws ValidationException {
        Person updated = repository.get(Person.class, primaryKey);

        BeanUtils.copyProperties(person, updated);

        repository.update(updated);
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public String getByUserName(String userName) throws EntityNotFoundException {
        Person person = repository.getByProperty(Person.class, "userName", userName);
        if (person == null) {
            log.warn("There is no person with the username '{}'", userName);
            throw new EntityNotFoundException("There is no person with the username '" + userName + "'");
        }

        return serialize(person, getDefaultFields());
    }

    @Override
    @Transactional(readOnly = false, propagation = Propagation.REQUIRED)
    public void delete(Integer primaryKey) throws EntityNotFoundException {
        repository.delete(Person.class, primaryKey);
    }

    @Override
    @Transactional(readOnly = true, propagation = Propagation.SUPPORTS)
    public void checkExisting(Person person) throws ValidationException {
        String userName = person.getUserName();
        Person existing = repository.getByProperty(Person.class, "userName", userName);
        if (existing != null) {
            throw new ValidationException("Exista deja un user cu username-ul '" + userName + "'");
        }
    }

    @Override
    public String getMetadata() {
        return getMetadata(EntityMetadata.Person);
    }
}
